package am.ik.clojure.servlet;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.logging.Logger;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import clojure.lang.RT;
import clojure.lang.Symbol;
import clojure.lang.Var;

@SuppressWarnings("serial")
public class ClojureServlet extends HttpServlet {
	private String cljDir;
	private String encoding;
	private static final Logger logger = Logger.getLogger(ClojureServlet.class
			.getName());

	@Override
	public void init(ServletConfig config) throws ServletException {
		logger.info("init");
		cljDir = config.getInitParameter("clj.dir");
		if (cljDir == null) {
			cljDir = "";
		}
		encoding = config.getInitParameter("encoding");
		if (encoding == null) {
			encoding = "UTF-8";
		}
	}

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		logger.info("service");
		resp.setContentType("text/html; charset=" + encoding);
		String path = req.getServletPath();
		logger.info(path);
		req.setCharacterEncoding(encoding);
		resp.setCharacterEncoding(encoding);
		try {
			// *out*をHttpServletResponseのOutputStreamに変更
			RT.OUT.doReset(new OutputStreamWriter(resp.getOutputStream()));
			// 文字列の出力のエスケープ処理を行わない
			Var readably = Var.find(Symbol.create(RT.CLOJURE_NS.toString(),
					"*print-readably*"));
			readably.doReset(RT.F);
			// HttpServletRequestを*request*にバインド
			Var.intern(RT.CLOJURE_NS, Symbol.create("*request*"), req);
			// HttpServletResponseを*response*にバインド
			Var.intern(RT.CLOJURE_NS, Symbol.create("*response*"), resp);

			try {
				RT.loadResourceScript(cljDir + path);
			} catch (Exception e) {
				logger.warning(e.getMessage());
				resp.sendError(HttpServletResponse.SC_NOT_FOUND);
			}
		} catch (Exception e) {
			logger.warning(e.getMessage());
			resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		}
	}
}
